home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / pd / netz / term / extras / source / term-source.lha / CustomRequest.c < prev    next >
C/C++ Source or Header  |  1995-02-06  |  19KB  |  839 lines

  1. /*
  2. **    CustomRequest.c
  3. **
  4. **    EasyRequest like custom requester
  5. **
  6. **    Copyright © 1990-1995 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* Pack two words into a long. */
  13.  
  14. #define PACK_ULONG(a,b)    (((ULONG)(a)) << 16 | b)
  15.  
  16.     /* Gadget extension. */
  17.  
  18. struct ButtonInfo
  19. {
  20.     struct Image    *ButtonImage;
  21.     UWORD         LabelLen,
  22.              LabelLeft,
  23.              LabelTop;
  24. };
  25.  
  26.     /* GetScreenInfo():
  27.      *
  28.      *    Obtain the currently visible screen area.
  29.      */
  30.  
  31. STATIC VOID __regargs
  32. GetScreenInfo(struct Screen *Screen,WORD *Left,WORD *Top,WORD *Width,WORD *Height)
  33. {
  34.     struct ViewPortExtra    *Extra;
  35.     struct TagItem         Tags[2] = { VTAG_VIEWPORTEXTRA_GET, NULL, TAG_DONE };
  36.  
  37.     if(!VideoControl(Screen -> ViewPort . ColorMap,Tags))
  38.         Extra = (struct ViewPortExtra *)Tags[0] . ti_Data;
  39.     else
  40.         Extra = NULL;
  41.  
  42.     if(!Extra)
  43.         Extra = Screen -> ViewPort . ColorMap -> cm_vpe;
  44.  
  45.     if(!Extra)
  46.         Extra = (struct ViewPortExtra *)GfxLookUp(&Screen -> ViewPort);
  47.  
  48.     if(Extra)
  49.     {
  50.         struct Rectangle Clip;
  51.  
  52.         QueryOverscan(GetVPModeID(&Screen -> ViewPort),&Clip,OSCAN_TEXT);
  53.  
  54.         *Width    = Extra -> DisplayClip . MaxX - Extra -> DisplayClip . MinX + 1;
  55.         *Height    = Extra -> DisplayClip . MaxY - Extra -> DisplayClip . MinY + 1;
  56.  
  57.         if(*Width < Clip . MaxX - Clip . MinX + 1)
  58.             *Width = Clip . MaxX - Clip . MinX + 1;
  59.  
  60.         if(*Height < Clip . MaxY - Clip . MinY + 1)
  61.             *Height = Clip . MaxY - Clip . MinY + 1;
  62.     }
  63.     else
  64.     {
  65.         *Width    = Screen -> Width;
  66.         *Height    = Screen -> Height;
  67.     }
  68.  
  69.     *Left    = ABS(Screen -> LeftEdge);
  70.     *Top    = ABS(Screen -> TopEdge);
  71.  
  72.     if(*Left > Screen -> Width || *Left < 0)
  73.         *Left = 0;
  74.  
  75.     if(*Top > Screen -> Height || *Top < 0)
  76.         *Top = 0;
  77. }
  78.  
  79.     /* CentreWindow():
  80.      *
  81.      *    Centre a window within the visible bounds of
  82.      *    a screen.
  83.      */
  84.  
  85. STATIC VOID __regargs
  86. CentreWindow(struct Screen *Screen,WORD Width,WORD Height,WORD *Left,WORD *Top)
  87. {
  88.     WORD ScreenWidth,ScreenHeight,ScreenLeft,ScreenTop;
  89.  
  90.     GetScreenInfo(Screen,&ScreenLeft,&ScreenTop,&ScreenWidth,&ScreenHeight);
  91.  
  92.     *Left    = ScreenLeft + (ScreenWidth - Width) / 2;
  93.     *Top    = ScreenTop + (ScreenHeight - Height) / 2;
  94. }
  95.  
  96.     /* RenderText():
  97.      *
  98.      *    Render the button text.
  99.      */
  100.  
  101. STATIC VOID __regargs
  102. RenderText(struct RastPort *RPort,struct GadgetInfo *GadgetInfo,struct Gadget *Gadget,struct ButtonInfo *ButtonInfo)
  103. {
  104.     STRPTR    Label = (STRPTR)Gadget -> GadgetText;
  105.     ULONG    State;
  106.     UWORD    Pen;
  107.  
  108.         /* Which state is the button in? */
  109.  
  110.     if(Gadget -> Flags & GFLG_SELECTED)
  111.     {
  112.         State    = IDS_SELECTED;
  113.         Pen    = GadgetInfo -> gi_DrInfo -> dri_Pens[FILLTEXTPEN];
  114.     }
  115.     else
  116.     {
  117.         State    = IDS_NORMAL;
  118.         Pen    = GadgetInfo -> gi_DrInfo -> dri_Pens[TEXTPEN];
  119.     }
  120.  
  121.         /* Render the frame. */
  122.  
  123.     DoMethod(Gadget -> GadgetRender,IM_DRAWFRAME,RPort,PACK_ULONG(Gadget -> LeftEdge,Gadget -> TopEdge),State,GadgetInfo -> gi_DrInfo,PACK_ULONG(Gadget -> Width,Gadget -> Height));
  124.  
  125.         /* Set the rendering pens. */
  126.  
  127.     if(IntuitionBase -> LibNode . lib_Version >= 39)
  128.         SetABPenDrMd(RPort,Pen,0,JAM1);
  129.     else
  130.     {
  131.         SetDrMd(RPort,JAM1);
  132.         SetAPen(RPort,Pen);
  133.     }
  134.  
  135.         /* Render the button label. */
  136.  
  137.     Move(RPort,Gadget -> LeftEdge + ButtonInfo -> LabelLeft,Gadget -> TopEdge + ButtonInfo -> LabelTop);
  138.     Text(RPort,Label,ButtonInfo -> LabelLen);
  139. }
  140.  
  141.     /* RenderButton():
  142.      *
  143.      *    Render the button label.
  144.      */
  145.  
  146. STATIC ULONG __regargs
  147. RenderButton(struct IClass *class,Object *object,struct gpRender *RenderInfo)
  148. {
  149.     RenderText(RenderInfo -> gpr_RPort,RenderInfo -> gpr_GInfo,(struct Gadget *)object,INST_DATA(class,object));
  150.  
  151.     return(TRUE);
  152. }
  153.  
  154.     /* FreeButton():
  155.      *
  156.      *    Free a button gadget object.
  157.      */
  158.  
  159. STATIC ULONG __regargs
  160. FreeButton(struct IClass *class,Object *object,Msg msg)
  161. {
  162.     struct ButtonInfo *ButtonInfo = INST_DATA(class,object);
  163.  
  164.     if(ButtonInfo -> ButtonImage)
  165.         DisposeObject(ButtonInfo -> ButtonImage);
  166.  
  167.     return(DoSuperMethodA(class,object,msg));
  168. }
  169.  
  170.     /* NewButton():
  171.      *
  172.      *    Create a new button object.
  173.      */
  174.  
  175. STATIC ULONG __regargs
  176. NewButton(struct IClass *class,Object *object,struct opSet *SetMethod)
  177. {
  178.     struct TagItem    *Tag,*TagList;
  179.     struct Gadget    *NewGadget    = NULL;
  180.     struct DrawInfo    *DrawInfo    = NULL;
  181.     STRPTR         Label        = NULL;
  182.  
  183.     TagList = SetMethod -> ops_AttrList;
  184.  
  185.     while(Tag = NextTagItem(&TagList))
  186.     {
  187.         switch(Tag -> ti_Tag)
  188.         {
  189.             case GA_Text:
  190.  
  191.                 Label = (STRPTR)Tag -> ti_Data;
  192.                 break;
  193.  
  194.             case GA_DrawInfo:
  195.  
  196.                 DrawInfo = (struct DrawInfo *)Tag -> ti_Data;
  197.                 break;
  198.         }
  199.     }
  200.  
  201.     if(Label && DrawInfo)
  202.     {
  203.         struct RastPort __aligned RastPort;
  204.  
  205.         UWORD Width,Height,LabelWidth,LabelHeight,LabelLen;
  206.  
  207.         LabelLen = strlen(Label);
  208.  
  209.         InitRastPort(&RastPort);
  210.  
  211.         SetFont(&RastPort,DrawInfo -> dri_Font);
  212.  
  213.         LabelWidth    = TextLength(&RastPort,Label,LabelLen);
  214.         LabelHeight    = RastPort . TxHeight;
  215.  
  216.         Width        = 2 + LabelWidth + (6 * RastPort . TxWidth) / 2;
  217.         Height        = 2 + LabelHeight + RastPort . TxHeight / 2;
  218.  
  219.         if(Width && Height)
  220.         {
  221.             struct Image *ButtonImage;
  222.  
  223.                 /* Create a button frame. */
  224.  
  225.             if(ButtonImage = NewObject(NULL,"frameiclass",
  226.                 IA_Width,    Width,
  227.                 IA_Height,    Height,
  228.             TAG_DONE))
  229.             {
  230.                 struct TagItem    *OldTags = SetMethod -> ops_AttrList,
  231.                          NewTags[4];
  232.  
  233.                     /* Add new tag values. */
  234.  
  235.                 NewTags[0] . ti_Tag    = GA_Image;
  236.                 NewTags[0] . ti_Data    = (ULONG)ButtonImage;
  237.                 NewTags[1] . ti_Tag    = GA_Width;
  238.                 NewTags[1] . ti_Data    = (ULONG)Width;
  239.                 NewTags[2] . ti_Tag    = GA_Height;
  240.                 NewTags[2] . ti_Data    = (ULONG)Height;
  241.                 NewTags[3] . ti_Tag    = TAG_MORE;
  242.                 NewTags[3] . ti_Data    = (ULONG)OldTags;
  243.  
  244.                 SetMethod -> ops_AttrList = NewTags;
  245.  
  246.                     /* Create new object. */
  247.  
  248.                 if(NewGadget = (struct Gadget *)DoSuperMethodA(class,object,(Msg)SetMethod))
  249.                 {
  250.                     struct ButtonInfo *ButtonInfo = INST_DATA(class,NewGadget);
  251.  
  252.                     ButtonInfo -> LabelLen    = LabelLen;
  253.                     ButtonInfo -> LabelLeft    = (Width - LabelWidth) / 2;
  254.                     ButtonInfo -> LabelTop    = RastPort . TxBaseline + (Height - LabelHeight) / 2;
  255.  
  256.                         /* Remember the frame image. */
  257.  
  258.                     ButtonInfo -> ButtonImage = ButtonImage;
  259.  
  260.                         /* Restore the tags. */
  261.  
  262.                     SetMethod -> ops_AttrList = OldTags;
  263.                 }
  264.                 else
  265.                     DisposeObject(ButtonImage);
  266.             }
  267.         }
  268.     }
  269.  
  270.     return((ULONG)NewGadget);
  271. }
  272.  
  273.     /* HandleButton():
  274.      *
  275.      *    Handle button input.
  276.      */
  277.  
  278. STATIC ULONG __regargs
  279. HandleButton(struct IClass *class,Object *object,struct gpInput *InputInfo)
  280. {
  281.     ULONG             Result        = GMR_MEACTIVE;
  282.     BOOL             Redraw        = FALSE,
  283.                  Final        = FALSE;
  284.     struct ButtonInfo    *ButtonInfo    = INST_DATA(class,object);
  285.     struct Gadget        *Button        = (struct Gadget *)object;
  286.  
  287.         /* Only mouse events trigger actions. */
  288.  
  289.     if(InputInfo -> gpi_IEvent -> ie_Class == IECLASS_RAWMOUSE)
  290.     {
  291.             /* Selection cancelled or no command available? */
  292.  
  293.         if(InputInfo -> gpi_IEvent -> ie_Code == MENUDOWN)
  294.         {
  295.             if(Button -> Flags & GFLG_SELECTED)
  296.             {
  297.                 Button -> Flags &= ~GFLG_SELECTED;
  298.  
  299.                 Redraw = TRUE;
  300.             }
  301.  
  302.             Result = GMR_NOREUSE;
  303.  
  304.                 /* No further actions, please. */
  305.  
  306.             Final = TRUE;
  307.         }
  308.         else
  309.         {
  310.                 /* Select button released? */
  311.  
  312.             if(InputInfo -> gpi_IEvent -> ie_Code == SELECTUP)
  313.             {
  314.                 if(DoMethod((Object *)ButtonInfo -> ButtonImage,IM_HITFRAME,PACK_ULONG(InputInfo -> gpi_Mouse . X,InputInfo -> gpi_Mouse . Y),PACK_ULONG(Button -> Width,Button -> Height)))
  315.                 {
  316.                     if(Button -> Flags & GFLG_SELECTED)
  317.                     {
  318.                         *InputInfo -> gpi_Termination = 0;
  319.  
  320.                         Button -> Flags &= ~GFLG_SELECTED;
  321.  
  322.                         Redraw = TRUE;
  323.                     }
  324.                     else
  325.                         *InputInfo -> gpi_Termination = 1;
  326.  
  327.                     Result = GMR_REUSE | GMR_VERIFY;
  328.                 }
  329.                 else
  330.                     Result = GMR_NOREUSE;
  331.  
  332.                     /* No further actions, please. */
  333.  
  334.                 Final = TRUE;
  335.             }
  336.         }
  337.     }
  338.         /* Change highlighting mode? */
  339.  
  340.     if(!Final)
  341.     {
  342.             /* Hit inside the boundaries? */
  343.  
  344.         if(DoMethod((Object *)ButtonInfo -> ButtonImage,IM_HITFRAME,PACK_ULONG(InputInfo -> gpi_Mouse . X,InputInfo -> gpi_Mouse . Y),PACK_ULONG(Button -> Width,Button -> Height)))
  345.         {
  346.             if(!(Button -> Flags & GFLG_SELECTED))
  347.             {
  348.                 Button -> Flags |= GFLG_SELECTED;
  349.  
  350.                 Redraw = TRUE;
  351.             }
  352.         }
  353.         else
  354.         {
  355.             if(Button -> Flags & GFLG_SELECTED)
  356.             {
  357.                 Button -> Flags &= ~GFLG_SELECTED;
  358.  
  359.                 Redraw = TRUE;
  360.             }
  361.         }
  362.     }
  363.  
  364.         /* Redraw the object? */
  365.  
  366.     if(Redraw)
  367.     {
  368.         struct RastPort *RPort;
  369.  
  370.         if(RPort = ObtainGIRPort(InputInfo -> gpi_GInfo))
  371.         {
  372.             RenderText(RPort,InputInfo -> gpi_GInfo,Button,ButtonInfo);
  373.  
  374.             ReleaseGIRPort(RPort);
  375.         }
  376.     }
  377.  
  378.     return(Result);
  379. }
  380.  
  381.     /* ButtonDispatch():
  382.      *
  383.      *    The button gadget class dispatcher.
  384.      */
  385.  
  386. STATIC ULONG __saveds __asm
  387. ButtonDispatch(register __a0 struct IClass *class,register __a2 Object *object,register __a1 Msg msg)
  388. {
  389.         /* Select the message method. */
  390.  
  391.     switch(msg -> MethodID)
  392.     {
  393.         case OM_NEW:
  394.  
  395.             return(NewButton(class,object,(struct opSet *)msg));
  396.  
  397.         case OM_DISPOSE:
  398.  
  399.             return(FreeButton(class,object,msg));
  400.  
  401.         case GM_RENDER:
  402.  
  403.             return(RenderButton(class,object,(struct gpRender *)msg));
  404.  
  405.         case GM_HITTEST:
  406.  
  407.             return(GMR_GADGETHIT);
  408.  
  409.         case GM_GOINACTIVE:
  410.  
  411.             return(0);
  412.  
  413.         case GM_GOACTIVE:
  414.  
  415.             return(GMR_MEACTIVE);
  416.  
  417.         case GM_HANDLEINPUT:
  418.  
  419.             return(HandleButton(class,object,(struct gpInput *)msg));
  420.  
  421.         default:
  422.  
  423.             return(DoSuperMethodA(class,object,msg));
  424.     }
  425. }
  426.  
  427.     /* DeleteButtonClass(VOID):
  428.      *
  429.      *    Free private button gadget class.
  430.      */
  431.  
  432. STATIC VOID __regargs
  433. DeleteButtonClass(Class *ButtonClass)
  434. {
  435.     if(ButtonClass)
  436.         FreeClass(ButtonClass);
  437. }
  438.  
  439.     /* CreateButtonClass(VOID):
  440.      *
  441.      *    Create private button gadget class.
  442.      */
  443.  
  444. STATIC Class *
  445. CreateButtonClass(VOID)
  446. {
  447.     Class *ButtonClass;
  448.  
  449.     if(ButtonClass = MakeClass(NULL,GADGETCLASS,NULL,sizeof(struct ButtonInfo),0))
  450.     {
  451.         ButtonClass -> cl_Dispatcher . h_Entry = (HOOKFUNC)ButtonDispatch;
  452.  
  453.         return(ButtonClass);
  454.     }
  455.     else
  456.         return(NULL);
  457. }
  458.  
  459.     /* DrawDent():
  460.      *
  461.      *    Draw a recessed box.
  462.      */
  463.  
  464. STATIC VOID __regargs
  465. DrawDent(struct RastPort *RPort,struct DrawInfo *DrawInfo,LONG Left,LONG Top,LONG Width,LONG Height)
  466. {
  467.     SetAPen(RPort,DrawInfo -> dri_Pens[BACKGROUNDPEN]);
  468.     RectFill(RPort,Left + 2,Top + 1,Left + Width - 3,Top + Height - 2);
  469.  
  470.     SetAPen(RPort,DrawInfo -> dri_Pens[SHADOWPEN]);
  471.     Move(RPort,Left + 1,Top + 1);
  472.     Draw(RPort,Left + 1,Top + Height - 1);
  473.     Draw(RPort,Left,Top + Height - 1);
  474.     Draw(RPort,Left,Top);
  475.     Draw(RPort,Left + Width - 2,Top);
  476.  
  477.     SetAPen(RPort,DrawInfo -> dri_Pens[SHINEPEN]);
  478.     Move(RPort,Left + 1,Top + Height - 1);
  479.     Draw(RPort,Left + Width - 1,Top + Height - 1);
  480.     Draw(RPort,Left + Width - 1,Top);
  481.     Draw(RPort,Left + Width - 2,Top + 1);
  482.     Draw(RPort,Left + Width - 2,Top + Height - 2);
  483. }
  484.  
  485. STATIC VOID
  486. StuffChar(VOID)
  487. {
  488.     __emit(0x16C0);    /* MOVE D0,(A3)+ */
  489. }
  490.  
  491. STATIC VOID __asm
  492. CountChar(register __a3 LONG *Count,register __d0 UBYTE Char)
  493. {
  494.     if(Char == '\n' || Char == '\0')
  495.         Count[1]++;
  496.  
  497.     Count[0]++;
  498. }
  499.  
  500.     /* ShowInfo():
  501.      *
  502.      *    Display an EasyRequest like information requester.
  503.      */
  504.  
  505. VOID __stdargs
  506. ShowInfo(struct Window *Parent,STRPTR Title,STRPTR Continue,STRPTR FormatString,...)
  507. {
  508.     struct Screen    *Screen,
  509.             *OldFrontScreen;
  510.     ULONG         IntuiLock;
  511.  
  512.     if(Parent)
  513.         Screen = Parent -> WScreen;
  514.     else
  515.         Screen = LockPubScreen(NULL);
  516.  
  517.     IntuiLock = LockIBase(NULL);
  518.  
  519.     if((OldFrontScreen = IntuitionBase -> FirstScreen) == Screen)
  520.         OldFrontScreen = NULL;
  521.  
  522.     UnlockIBase(IntuiLock);
  523.  
  524.     if(Screen)
  525.     {
  526.         struct DrawInfo *DrawInfo;
  527.  
  528.         if(OldFrontScreen)
  529.             ScreenToFront(Screen);
  530.  
  531.         if(DrawInfo = GetScreenDrawInfo(Screen))
  532.         {
  533.             Class *ButtonClass;
  534.  
  535.             if(ButtonClass = CreateButtonClass())
  536.             {
  537.                 struct Gadget *Button;
  538.  
  539.                 if(Button = NewObject(ButtonClass,NULL,
  540.                     GA_Text,    Continue,
  541.                     GA_DrawInfo,    DrawInfo,
  542.                     GA_RelVerify,    TRUE,
  543.                 TAG_DONE))
  544.                 {
  545.                     va_list    VarArgs;
  546.                     LONG    Information[2];
  547.                     STRPTR    Data;
  548.  
  549.                     Information[0] = Information[1] = 0;
  550.  
  551.                     va_start(VarArgs,FormatString);
  552.                     RawDoFmt(FormatString,VarArgs,(VOID (*)())CountChar,Information);
  553.                     va_end(VarArgs);
  554.  
  555.                     if(Data = (STRPTR)AllocVec(Information[0],MEMF_ANY))
  556.                     {
  557.                         LONG            i,Lines = Information[1],Start,Len;
  558.                         WORD            Width = 0,Height,Left,Top;
  559.                         struct IntuiText    IText;
  560.                         struct Window        *Window;
  561.                         struct TextFont        *Font = DrawInfo -> dri_Font;
  562.  
  563.                         WORD            WindowLeft,WindowTop,
  564.                                     WindowWidth,WindowHeight,
  565.                                     ScreenWidth,ScreenHeight,
  566.                                     ScreenLeft,ScreenTop;
  567.  
  568.                         va_start(VarArgs,FormatString);
  569.                         RawDoFmt(FormatString,VarArgs,(VOID (*)())StuffChar,Data);
  570.                         va_end(VarArgs);
  571.  
  572.                         memset(&IText,0,sizeof(struct IntuiText));
  573.  
  574.                         IText . ITextFont = Screen -> Font;
  575.  
  576.                         for(i = Start = 0 ; i < Information[0] ; i++)
  577.                         {
  578.                             if(!Data[i])
  579.                             {
  580.                                 IText . IText = &Data[Start];
  581.  
  582.                                 if((Len = IntuiTextLength(&IText)) > Width)
  583.                                     Width = Len;
  584.  
  585.                                 Start = i + 1;
  586.                             }
  587.                             else
  588.                             {
  589.                                 if(Data[i] == '\n')
  590.                                 {
  591.                                     if(Start != i)
  592.                                     {
  593.                                         Data[i] = 0;
  594.  
  595.                                         IText . IText = &Data[Start];
  596.  
  597.                                         Len = IntuiTextLength(&IText);
  598.  
  599.                                         Data[i] = '\n';
  600.  
  601.                                         if(Len > Width)
  602.                                             Width = Len;
  603.                                     }
  604.  
  605.                                     Start = i + 1;
  606.                                 }
  607.                             }
  608.                         }
  609.  
  610.                         Len = Button -> Width + 2 * Font -> tf_XSize;
  611.  
  612.                         if(Width < Len)
  613.                             Width = Len;
  614.  
  615.                         Width    = Screen -> WBorLeft + 4 + 3 * Font -> tf_XSize + Width + Screen -> WBorRight;
  616.                         Height    = Screen -> WBorTop + Screen -> Font -> ta_YSize + 1 + Font -> tf_YSize / 2 + (2 + Lines) * Font -> tf_YSize + Button -> Height + Screen -> WBorBottom;
  617.  
  618.                         if(Parent)
  619.                         {
  620.                             WindowLeft    = Parent -> LeftEdge + Parent -> BorderLeft;
  621.                             WindowTop    = Parent -> TopEdge + Parent -> BorderTop;
  622.                             WindowWidth    = Parent -> Width - (Parent -> BorderLeft + Parent -> BorderRight);
  623.                             WindowHeight    = Parent -> Height - (Parent ->BorderTop + Parent -> BorderBottom);
  624.  
  625.                             if((Left = WindowLeft + (WindowWidth - Width) / 2) < 0)
  626.                                 Left = 0;
  627.  
  628.                             if((Top = WindowTop + (WindowHeight - Height) / 2) < 0)
  629.                                 Top = 0;
  630.  
  631.                             GetScreenInfo(Screen,&ScreenLeft,&ScreenTop,&ScreenWidth,&ScreenHeight);
  632.  
  633.                             if(Left < ScreenLeft || Left + Width > ScreenLeft + ScreenWidth)
  634.                                 Left = -1;
  635.  
  636.                             if(Top < ScreenTop || Top + Height > ScreenTop + ScreenHeight)
  637.                                 Top = -1;
  638.  
  639.                             if(Top == -1 || Left == -1)
  640.                                 CentreWindow(Screen,Width,Height,&Left,&Top);
  641.                         }
  642.                         else
  643.                             CentreWindow(Screen,Width,Height,&Left,&Top);
  644.  
  645.                         if(Window = OpenWindowTags(NULL,
  646.                             WA_Left,    Left,
  647.                             WA_Top,        Top,
  648.                             WA_Width,    Width,
  649.                             WA_Height,    Height,
  650.                             WA_Title,    Title,
  651.                             WA_DragBar,    TRUE,
  652.                             WA_DepthGadget,    TRUE,
  653.                             WA_RMBTrap,    TRUE,
  654.                             WA_IDCMP,    IDCMP_GADGETUP | IDCMP_VANILLAKEY | IDCMP_RAWKEY,
  655.                             WA_Activate,    TRUE,
  656.                             WA_CustomScreen,Screen,
  657.                         TAG_DONE))
  658.                         {
  659.                             struct IntuiMessage    *Message;
  660.                             struct RastPort        *RPort = Window -> RPort;
  661.                             BOOL             Terminated    = FALSE,
  662.                                          KeyHit        = FALSE;
  663.  
  664.                             if(GfxBase -> LibNode . lib_Version >= 39)
  665.                             {
  666.                                 LONG MaxPen = 0;
  667.  
  668.                                 for(i = 0 ; i < DrawInfo -> dri_NumPens ; i++)
  669.                                 {
  670.                                     if(DrawInfo -> dri_Pens[i] > MaxPen)
  671.                                         MaxPen = DrawInfo -> dri_Pens[i];
  672.                                 }
  673.  
  674.                                 SetMaxPen(Window -> RPort,MaxPen);
  675.                             }
  676.  
  677.                             SetFont(RPort,Font);
  678.  
  679.                             if(GfxBase -> LibNode . lib_Version >= 39)
  680.                                 SetABPenDrMd(RPort,DrawInfo -> dri_Pens[SHINEPEN],DrawInfo -> dri_Pens[BACKGROUNDPEN],JAM2);
  681.                             else
  682.                             {
  683.                                 SetAPen(RPort,DrawInfo -> dri_Pens[SHINEPEN]);
  684.                                 SetBPen(RPort,DrawInfo -> dri_Pens[BACKGROUNDPEN]);
  685.                                 SetDrMd(RPort,JAM2);
  686.                             }
  687.  
  688.                             LockLayerRom(Window -> RPort -> Layer);
  689.  
  690.                             SetAfPt(RPort,(UWORD *)&Crosshatch,1);
  691.                             RectFill(RPort,Window -> BorderLeft,Window -> BorderTop,Window -> Width - (Window -> BorderRight + 1),Window -> Height - (Window -> BorderBottom + 1));
  692.                             SetAfPt(RPort,NULL,0);
  693.  
  694.                             Left    = Window -> BorderLeft + RPort -> Font -> tf_XSize;
  695.                             Top    = Window -> BorderTop + RPort -> Font -> tf_YSize / 2;
  696.                             Width    = Window -> Width - (Window -> BorderRight + 2 * RPort -> Font -> tf_XSize + Window -> BorderLeft);
  697.                             Height    = (1 + Lines) * RPort -> Font -> tf_YSize;
  698.  
  699.                             SetDrMd(RPort,JAM1);
  700.  
  701.                             DrawDent(RPort,DrawInfo,Left,Top,Width,Height);
  702.  
  703.                             SetAttrs(Button,
  704.                                 GA_Left,    (Window -> Width - Button -> Width) / 2,
  705.                                 GA_Top,        Window -> BorderTop + Font -> tf_YSize / 2 + (1 + Lines) * Font -> tf_YSize + (Window -> Height - (Window -> BorderTop + Font -> tf_YSize / 2 + (1 + Lines) * Font -> tf_YSize + Window -> BorderBottom) - Button -> Height) / 2,
  706.                             TAG_DONE);
  707.  
  708.                             UnlockLayerRom(Window -> RPort -> Layer);
  709.  
  710.                             AddGadget(Window,Button,(UWORD)~0);
  711.                             RefreshGList(Button,Window,NULL,1);
  712.  
  713.                             LockLayerRom(Window -> RPort -> Layer);
  714.  
  715.                             SetAPen(RPort,DrawInfo -> dri_Pens[TEXTPEN]);
  716.  
  717.                             Top = Window -> BorderTop + Font -> tf_YSize + Font -> tf_Baseline;
  718.  
  719.                             for(i = Start = 0 ; i < Information[0] ; i++)
  720.                             {
  721.                                 if(!Data[i])
  722.                                 {
  723.                                     Move(RPort,(Window -> Width - TextLength(RPort,&Data[Start],strlen(&Data[Start]))) / 2,Top);
  724.                                     Text(RPort,&Data[Start],strlen(&Data[Start]));
  725.  
  726.                                     Top += Font -> tf_YSize;
  727.                                 }
  728.                                 else
  729.                                 {
  730.                                     if(Data[i] == '\n')
  731.                                     {
  732.                                         if(Start != i)
  733.                                         {
  734.                                             Data[i] = 0;
  735.  
  736.                                             Move(RPort,(Window -> Width - TextLength(RPort,&Data[Start],strlen(&Data[Start]))) / 2,Top);
  737.                                             Text(RPort,&Data[Start],strlen(&Data[Start]));
  738.                                         }
  739.  
  740.                                         Top += Font -> tf_YSize;
  741.  
  742.                                         Start = i + 1;
  743.                                     }
  744.                                 }
  745.                             }
  746.  
  747.                             UnlockLayerRom(Window -> RPort -> Layer);
  748.  
  749.                             do
  750.                             {
  751.                                 WaitPort(Window -> UserPort);
  752.  
  753.                                 while(Message = (struct IntuiMessage *)GetMsg(Window -> UserPort))
  754.                                 {
  755.                                     if(Message -> Class == IDCMP_GADGETUP)
  756.                                         Terminated = TRUE;
  757.  
  758.                                     if(Message -> Class == IDCMP_VANILLAKEY)
  759.                                     {
  760.                                         if(Message -> Code == '\33' || Message -> Code == '\r')
  761.                                             KeyHit = Terminated = TRUE;
  762.                                     }
  763.  
  764.                                     if(Message -> Class == IDCMP_RAWKEY)
  765.                                     {
  766.                                         UWORD Code = Message -> Code;
  767.  
  768.                                         ReplyMsg((struct Message *)Message);
  769.  
  770.                                         if(Code == HELP_CODE)
  771.                                             GuideDisplay(CONTEXT_MAIN);
  772.                                     }
  773.                                     else
  774.                                         ReplyMsg((struct Message *)Message);
  775.                                 }
  776.                             }
  777.                             while(!Terminated);
  778.  
  779.                             if(KeyHit)
  780.                             {
  781.                                 SetAttrs(Button,GA_Selected,TRUE,TAG_DONE);
  782.                                 RefreshGList(Button,Window,NULL,1);
  783.  
  784.                                 WaitTime(0,80000);
  785.  
  786.                                 SetAttrs(Button,GA_Selected,FALSE,TAG_DONE);
  787.                                 RefreshGList(Button,Window,NULL,1);
  788.                             }
  789.  
  790.                             CloseWindow(Window);
  791.                         }
  792.  
  793.                         FreeVec(Data);
  794.                     }
  795.  
  796.                     DisposeObject(Button);
  797.                 }
  798.  
  799.                 DeleteButtonClass(ButtonClass);
  800.             }
  801.  
  802.             FreeScreenDrawInfo(Screen,DrawInfo);
  803.         }
  804.  
  805.         if(!Parent)
  806.             UnlockPubScreen(NULL,Screen);
  807.     }
  808.  
  809.     if(OldFrontScreen)
  810.     {
  811.         struct Screen *NewFrontScreen = NULL,*Screen;
  812.  
  813.         Forbid();
  814.  
  815.         IntuiLock = LockIBase(NULL);
  816.  
  817.         Screen = IntuitionBase -> FirstScreen;
  818.  
  819.         while(Screen)
  820.         {
  821.             if(Screen == OldFrontScreen)
  822.             {
  823.                 NewFrontScreen = Screen;
  824.  
  825.                 break;
  826.             }
  827.             else
  828.                 Screen = Screen -> NextScreen;
  829.         }
  830.  
  831.         UnlockIBase(IntuiLock);
  832.  
  833.         if(NewFrontScreen)
  834.             ScreenToFront(NewFrontScreen);
  835.  
  836.         Permit();
  837.     }
  838. }
  839.